/// 交互式命令行界面工具
///
/// 提供用户友好的交互式界面，帮助用户配置扩展项目生成参数
use crate::cli::{ExtensionType, LayerType};
use anyhow::Result;
use colored::*;
use inquire::{Confirm, MultiSelect, Select, Text};
use std::path::PathBuf;

/// 交互式扩展类型选择
pub async fn select_extension_type() -> Result<ExtensionType> {
    let extension_types = vec![ExtensionType::Standard, ExtensionType::Api, ExtensionType::Core, ExtensionType::Lightweight, ExtensionType::Custom];

    println!("{}", "📋 选择扩展类型".bold().cyan());
    println!();

    let selection = Select::new("请选择扩展类型:", extension_types).with_help_message("不同类型包含不同的层组合，适用于不同场景").prompt()?;

    Ok(selection)
}

/// 交互式层选择（用于自定义类型）
pub async fn select_custom_layers() -> Result<Vec<LayerType>> {
    let all_layers = vec![LayerType::Nodes, LayerType::Plugins, LayerType::Commands, LayerType::Router];

    println!("{}", "🔧 自定义层选择".bold().cyan());
    println!();

    let selected = MultiSelect::new("选择要包含的层:", all_layers)
        .with_formatter(&|layers| {
            if layers.is_empty() {
                "未选择任何层".red().to_string()
            } else {
                layers.iter().map(|l| format!("{:?}", l)).collect::<Vec<_>>().join(", ").green().to_string()
            }
        })
        .with_help_message("使用空格键选择/取消选择，回车确认")
        .prompt()?;

    if selected.is_empty() {
        println!("{}", "⚠️  警告：未选择任何层，将使用默认的 Nodes 层".yellow());
        Ok(vec![LayerType::Nodes])
    } else {
        Ok(selected)
    }
}

/// 交互式项目信息收集
pub async fn collect_project_info(name: Option<String>) -> Result<ProjectInfo> {
    println!("{}", "📝 项目基本信息".bold().cyan());
    println!();

    // 扩展名称
    let name = if let Some(name) = name {
        name
    } else {
        Text::new("扩展名称:").with_help_message("使用 kebab-case 格式，如：my-extension").with_validator(validate_extension_name).prompt()?
    };

    // 扩展描述
    let description =
        Text::new("扩展描述:").with_default(&format!("{} extension for Price-RS", name)).with_help_message("简单描述扩展的功能和用途").prompt()?;

    // 作者信息
    let author = Text::new("作者:").with_default("Price-RS Team").with_help_message("作者或团队名称").prompt()?;

    // 输出目录
    let default_output = format!("extension-{}", name);
    let output_dir = Text::new("输出目录:").with_default(&default_output).with_help_message("项目将生成到此目录").prompt()?;

    Ok(ProjectInfo { name, description, author, output_dir: PathBuf::from(output_dir) })
}

/// 交互式确认生成配置
pub async fn confirm_generation(
    project_info: &ProjectInfo,
    extension_type: &ExtensionType,
    layers: &[LayerType],
) -> Result<bool> {
    println!();
    println!("{}", "📋 生成配置确认".bold().cyan());
    println!();

    // 显示配置摘要
    println!("  {} {}", "名称:".cyan(), project_info.name.bold());
    println!("  {} {}", "描述:".cyan(), project_info.description);
    println!("  {} {:?}", "类型:".cyan(), extension_type);
    println!("  {} {}", "输出:".cyan(), project_info.output_dir.display());
    println!("  {} {}", "作者:".cyan(), project_info.author);

    println!();
    println!("  {} 包含的层:", "🏗️".bold());
    for layer in layers {
        println!("    {} {} - {}", "✓".green(), format!("{:?}", layer).bold(), layer.description().italic());
    }

    println!();

    // 检查输出目录是否存在
    let output_exists = project_info.output_dir.exists();
    if output_exists {
        println!(
            "{} {} {}",
            "⚠️".yellow(),
            "警告:".yellow().bold(),
            format!("目录 {} 已存在，将会覆盖现有文件", project_info.output_dir.display()).yellow()
        );
        println!();
    }

    // 确认生成
    let confirm_msg = if output_exists { "确定要生成项目吗？（这将覆盖现有文件）" } else { "确定要生成项目吗？" };

    let confirmed = Confirm::new(confirm_msg).with_default(true).with_help_message("选择 'y' 开始生成，'n' 取消操作").prompt()?;

    Ok(confirmed)
}

/// 显示生成进度和结果
pub async fn show_generation_progress() -> Result<()> {
    println!();
    println!("{}", "🚀 开始生成项目...".bold().cyan());

    // 这里可以添加实际的进度显示逻辑
    // 目前只是显示静态消息

    Ok(())
}

/// 显示生成完成信息
pub async fn show_completion_message(
    project_info: &ProjectInfo,
    layers: &[LayerType],
) -> Result<()> {
    println!();
    println!("{}", "🎉 项目生成完成！".bold().green());
    println!();

    // 显示下一步操作
    println!("{}", "🚀 下一步操作:".bold());
    println!("  1. {} {}", "进入项目目录:".cyan(), format!("cd {}", project_info.output_dir.display()).yellow());
    println!("  2. {} {}", "编译项目:".cyan(), "cargo build".yellow());
    println!("  3. {} {}", "运行测试:".cyan(), "cargo test".yellow());

    if layers.contains(&LayerType::Router) {
        println!("  4. {} {}", "启动开发服务器:".cyan(), "cargo run --bin dev-server".yellow());
    }

    println!();
    println!("{} {} {}", "💡".bold(), "提示:".bold().cyan(), "生成的代码包含TODO标记，请根据实际需求完善业务逻辑。".italic());

    Ok(())
}

/// 项目信息结构
#[derive(Debug, Clone)]
pub struct ProjectInfo {
    pub name: String,
    pub description: String,
    pub author: String,
    pub output_dir: PathBuf,
}

/// 验证扩展名称
fn validate_extension_name(input: &str) -> Result<inquire::validator::Validation, Box<dyn std::error::Error + Send + Sync>> {
    if input.trim().is_empty() {
        return Ok(inquire::validator::Validation::Invalid("扩展名称不能为空".into()));
    }

    if input.len() > 50 {
        return Ok(inquire::validator::Validation::Invalid("扩展名称不能超过50个字符".into()));
    }

    if !input.chars().all(|c| c.is_alphanumeric() || c == '-') {
        return Ok(inquire::validator::Validation::Invalid("扩展名称只能包含字母、数字和连字符".into()));
    }

    if input.starts_with('-') || input.ends_with('-') {
        return Ok(inquire::validator::Validation::Invalid("扩展名称不能以连字符开始或结束".into()));
    }

    if input.contains("--") {
        return Ok(inquire::validator::Validation::Invalid("扩展名称不能包含连续的连字符".into()));
    }

    Ok(inquire::validator::Validation::Valid)
}

/// 交互式配置向导
pub async fn run_config_wizard() -> Result<crate::config::Config> {
    println!("{}", "⚙️  配置向导".bold().cyan());
    println!("{}", "设置默认配置选项，提升后续使用体验。".italic());
    println!();

    let mut config = crate::config::Config::default();

    // 默认作者
    let author = Text::new("默认作者:").with_default("Price-RS Team").with_help_message("新项目的默认作者信息").prompt()?;
    config.default_author = Some(author);

    // 默认扩展类型
    let default_type =
        Select::new("默认扩展类型:", vec!["standard", "api", "core", "lightweight"]).with_help_message("创建新扩展时的默认类型").prompt()?;
    config.default_extension_type = Some(default_type.to_string());

    // 行为配置
    println!();
    println!("{}", "行为配置:".bold().cyan());

    config.behavior.auto_format =
        Confirm::new("自动格式化生成的代码？").with_default(true).with_help_message("使用 rustfmt 自动格式化生成的 Rust 代码").prompt()?;

    config.behavior.generate_tests = Confirm::new("生成测试文件？").with_default(true).with_help_message("在生成的代码中包含测试用例").prompt()?;

    config.behavior.generate_docs = Confirm::new("生成文档文件？").with_default(true).with_help_message("生成 README 和其他文档文件").prompt()?;

    // 保存配置
    println!();
    let save_config = Confirm::new("保存配置？").with_default(true).with_help_message("配置将保存到用户配置文件").prompt()?;

    if save_config {
        config.save()?;
        println!("{}", "✅ 配置已保存".bold().green());
    }

    Ok(config)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validate_extension_name() {
        // 有效名称
        assert!(matches!(validate_extension_name("djgc"), Ok(inquire::validator::Validation::Valid)));
        assert!(matches!(validate_extension_name("fbfx-csxm"), Ok(inquire::validator::Validation::Valid)));

        // 无效名称
        assert!(matches!(validate_extension_name(""), Ok(inquire::validator::Validation::Invalid(_))));
        assert!(matches!(validate_extension_name("-invalid"), Ok(inquire::validator::Validation::Invalid(_))));
        assert!(matches!(validate_extension_name("invalid--name"), Ok(inquire::validator::Validation::Invalid(_))));
    }

    #[test]
    fn test_project_info() {
        let info = ProjectInfo {
            name: "test-extension".to_string(),
            description: "Test extension".to_string(),
            author: "Test Author".to_string(),
            output_dir: PathBuf::from("./test-output"),
        };

        assert_eq!(info.name, "test-extension");
        assert_eq!(info.description, "Test extension");
        assert_eq!(info.author, "Test Author");
    }
}
